APCS FracCalc (Java code):
/********************************************************************************************************************************************************************/
/*Frac Calc Final: All requirements complete Assignment AP Computer Science
 *Sriram Yadavalli
/********************************************************************************************************************************************************************/


import java.util.Scanner;


public class FracCalc 
{

   /*
   *   main() method creates a Scanner, reads one line of input, and passes that input to produceAnswer.
   *   main() prints the result returned by produceAnswer.
   *   If the input is the string “test”, then call your runTests() method to run your test cases.
   *   main() method accepts input from the user multiple times, until the user types “quit” (case-insensitive).
   */
   public static void main (String [] args) 
   {
      System.out.println("Welcome to FracCalc.");
      for (;;) 
      {
         System.out.println("\nPlease Enter a two operand expression (seperated by spaces before and after the operator) OR \"test\" for a test run OR \"quit\" to exit:");
         Scanner UserInput = new Scanner (System.in);
         UserInput.useDelimiter("\r");
         String inputString = UserInput.next();
         
         if (inputString.equals("test"))
         {
            runTests();
         }
         else if (inputString.toLowerCase().equals("quit"))
         {
            System.out.println("Hope you enjoyed FracCalc. Thank you.");
            return;
         }
         else
         {
            String valueString = produceAnswer (inputString);
            System.out.println (valueString);
         }
      }
   }
   
   
   /*
   *   produceAnswer breaks up that line of input into three Strings: the first operand (fraction), the operator (+ - * /), and the second operand (fraction).
   *   Each of these Strings are stored in variables inside produceAnswer.
   *   
   *   produceAnswer evaluates the formula it is given (performing addition, subtraction, multiplication, or division, based on the operator specified)
   *
   *   returns a string of the decimal value of evaluated expression.
   */
   
   public static String produceAnswer (String question) 
   {
      String secondOperand = "0", firstOperand = "0", operator = "0";
      
      
           
      int index = question.indexOf(" ");
     
      firstOperand = question.substring(0, index);
     
      secondOperand = question.substring(index + 3);
      
      double firstValue = fracStringToDouble(firstOperand);
      double secondValue = fracStringToDouble(secondOperand);
      double finalValue = 0;
      String finalValueString = "0";
      
      
      
       if (question.contains(" + "))
      {
         finalValue = firstValue + secondValue;
      }
      else if (question.contains(" - "))
      {
         finalValue = firstValue - secondValue;
      }
      else if (question.contains(" * "))
      {
         finalValue = firstValue * secondValue;
      }
      else if (question.contains(" / "))
      {
         finalValue = firstValue / secondValue;
      }
      
      finalValueString = Double.toString(finalValue);
      String mantissa = "0";
      String mantissa_reduced = "0";
      String wholeNum = "0";
      double mantDenom = 1;
      int indexDec = finalValueString.indexOf(".");
      String reducedFracString = "0";
      
      if (indexDec >= 0)
      {
         mantissa = finalValueString.substring(indexDec + 1, finalValueString.length());
         mantissa_reduced = mantissa.substring(0,2);
         wholeNum = finalValueString.substring(0, indexDec);
         mantDenom = Math.pow(10, (double)mantissa_reduced.length());
         
         String mantDenomString = Integer.toString((int)mantDenom);
         
         if (wholeNum.equals("0") || wholeNum.equals("-0") || wholeNum.equals("+0"))
         {
            finalValueString = (mantissa_reduced + "/" + mantDenomString);
         }
         else
         {
            finalValueString = (wholeNum + "_" + mantissa_reduced + "/" + mantDenomString);
         }

         reducedFracString = reduceFraction (Double.parseDouble(mantissa_reduced), mantDenom);
      }
 
      
      if (wholeNum.equals("0") || wholeNum.equals("-0") || wholeNum.equals("+0"))
      {
         finalValueString = reducedFracString;
      }
      else
      {
         finalValueString = wholeNum + "_" + reducedFracString;
      }
      
      return finalValueString;
     
   }
   
   private static String reduceFraction (double numerator, double denominator)
   {
        // find the largest number that divide the numerator and
        // denominator evenly
        double gcd = 0;
        for (double i = denominator; i >= 2; i--) {
        //System.out.println(gcd);
            if (numerator % i == 0 && denominator % i == 0) {
                gcd = i;
                break;
            }
        }

        // divide the largest common denominator out of numerator, denominator
        if (gcd != 0) {
            numerator /= gcd;
            denominator /= gcd;
        }
        
        int numint = (int) numerator;
        int numden = (int) denominator;
        
        return numint + "/" + numden;
   }
   
   
   /*
   *   fracStringToDouble returns the decimal value of a fraction input as a string.
   */   
   
   private static double fracStringToDouble (String fraction)
   {
      double fracValue = 0;
      double dbWhole = 0;
      double dbDenominator = 0;
      double dbNumerator = 0;
      
      String whole = "0", denominator = "1", numerator = "0";
      int indexUS = -1, indexSlash = -1;
      
      indexUS = fraction.indexOf("_");
      indexSlash = fraction.indexOf("/");
      
      if (fraction.contains("_"))
      {
         whole = fraction.substring(0, indexUS);
      }
      else if (!((fraction.contains("/") || fraction.contains("_"))))
      {
         whole = fraction;
      }
      
      if (fraction.contains("/") &&! fraction.contains("_"))
      {
         numerator = fraction.substring(0, indexSlash);
         denominator = fraction.substring(indexSlash + 1, fraction.length());
      }
      else if (fraction.contains("/") && fraction.contains("_"))
      {
         numerator = fraction.substring(indexUS + 1, indexSlash);
         denominator = fraction.substring(indexSlash + 1, fraction.length());
      }
      
      dbWhole = (double) Integer.parseInt(whole);
      dbDenominator = (double) Integer.parseInt(denominator);
      dbNumerator = (double) Integer.parseInt(numerator);
      
      if(dbWhole > 0)
      {
         fracValue = (dbWhole*dbDenominator + dbNumerator)/dbDenominator;  
      } 
      else if(dbWhole < 0)
      {
         fracValue = -1 * (Math.abs(dbWhole) * dbDenominator + dbNumerator)/dbDenominator;   
      }
      else
         fracValue = dbWhole + (dbNumerator / dbDenominator);   
         
      return fracValue;
   }
   
   public static void runTests () 
   {
      System.out.println(produceAnswer("5_3/4 - 6_5/8"));
      System.out.println(produceAnswer("-3/7 + 20"));
      System.out.println(produceAnswer("-32 - 27/21"));
      System.out.println(produceAnswer("1_1/4 * -2_5/7"));
   }
}